package com.weishuang.monitor.leader.config.client;

import cn.hutool.json.JSONUtil;
import com.weishuang.monitor.leader.commons.entity.Result;
import com.weishuang.monitor.leader.commons.enums.ICODE;
import com.weishuang.monitor.leader.commons.jwt.JWTInfo;
import com.weishuang.monitor.leader.commons.jwt.JwtTokenUtil;
import com.weishuang.monitor.leader.commons.utils.ResultUtils;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    private JwtTokenUtil jwtTokenUtil;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager, AuthenticationEntryPoint authenticationEntryPoint) {
        super(authenticationManager, authenticationEntryPoint);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        //判断token是否存在
        String authorization = httpServletRequest.getHeader("Authorization");
        //存在进行解析处理
        if (StringUtils.isNotBlank(authorization)) {
            try {
                JWTInfo infoFromToken = jwtTokenUtil.getInfoFromToken(authorization);
                if (infoFromToken != null) {
                    ClientUserDetails clientUserDetails = new ClientUserDetails();
                    clientUserDetails.setUsername(infoFromToken.getClientId());
                    clientUserDetails.setSystemName(infoFromToken.getSystemName());
                    //客户端默认权限为ROLE_CLIENT
                    Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
                    grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_CLIENT"));
                    ClientAuthenticationToken clientAuthenticationToken = new ClientAuthenticationToken(clientUserDetails, null, grantedAuthorities);
                    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                    if (authentication == null) {
                        SecurityContextHolder.getContext().setAuthentication(clientAuthenticationToken);
                    }
                } else {
                    Result info = ResultUtils.info(ICODE.TOKEN_TIME_OUT);
                    httpServletResponse.setStatus(200);
                    httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                    httpServletResponse.getWriter().write(JSONUtil.toJsonPrettyStr(info));
                    return;
                }
            } catch (ExpiredJwtException e) {
                //如果解析失败，打印异常后返回
                log.error(e.getMessage(), e);
                Result info = ResultUtils.info(ICODE.TOKEN_TIME_OUT);
                httpServletResponse.setStatus(200);
                httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                httpServletResponse.getWriter().write(JSONUtil.toJsonPrettyStr(info));
                return;
            } catch (Exception e) {
                //如果解析失败，打印异常后返回
                log.error(e.getMessage(), e);
                Result info = ResultUtils.info(ICODE.LOGIN_ERROR);
                httpServletResponse.setStatus(200);
                httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                httpServletResponse.getWriter().write(JSONUtil.toJsonPrettyStr(info));
                return;
            }
        }
        //存不存在都之前其他过滤区
        filterChain.doFilter(httpServletRequest,httpServletResponse);
    }

    public void setJwtTokenUtil(JwtTokenUtil jwtTokenUtil) {
        this.jwtTokenUtil = jwtTokenUtil;
    }
}
